//
//  Created by 朕与将军解战袍 on 2022/3/12.
//

#include <string.h>
#include <time.h>
#include <stdio.h>

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "include/stb_image_write.h"

#define TTF_RENDER_IMPLEMENT
#include "glyph.h"
#include "raster.h"

void seedFillTest() {
    unsigned char bitmap[500][500];
    memset(bitmap, EMPTY, sizeof(bitmap));

    BezierQuadratic curve[] = {
            {
            .p0 = {0.0, 0.0},
            .p1 = {10.0, 320.0},
            .p2 = {320.0, 128.0}
            },
            {
            .p0 = {0.0, 0.0},
            .p1 = {260.0, 100.0},
            .p2 = {320.0, 128.0}
            }
    };
    Glyph glyph = {
            .data = &curve,
            .size = sizeof(curve) / sizeof(BezierQuadratic),
            .type = BEZIER_QUADRATIC,
            };

    clock_t start = clock();
    seedFillGlyph((unsigned char *) bitmap, 500, 500, &glyph, 1);
    clock_t end = clock();

    printf("total time = %ld ms", end - start);
    stbi_write_bmp("bezier.bmp", 500, 500, 1, bitmap);
}

#include "ttf_info.h"

int main() {
    // open file
    FILE *test_ttf = fopen("./test.ttf", "rb");
    if (test_ttf == NULL) {
        printf("ERROR: can not read file.\n");
        return -1;
    }
    // get file size
    uint64_t size;
    fseek(test_ttf, 0, SEEK_END);
    size = ftell(test_ttf);
    fseek(test_ttf, 0, SEEK_SET);
    // read file
    char *buf = malloc(size);
    fread(buf, 1, size, test_ttf);
    // get ttf file info
    TTFStatus status = SUCCESS;
    TTFInfo info;
    status =  initTTFInfo(buf, &info);
    if (TTF_ERR(status)) {
        printf("ERROR: invalid ttf file.\n");
        return -1;
    }
    // get head table
    HeadTable headTable;
    status = getHeadTable(&info, &headTable);
    if (TTF_ERR(status)) {
        switch (status) {
            case TABLE_NOT_FOUND:
                printf("ERROR: Can not found head table.\n");
                break;
            case INVALID_PARAMETER:
                printf("ERROR: INVALID TABLE DATA.\n");
                break;
        }
        return -1;
    }
    // get maxp table
    MaxpTable maxpTable;
    status = getMaxpTable(&info, &maxpTable);
    if (TTF_ERR(status)) {
        switch (status) {
            case TABLE_NOT_FOUND:
                printf("ERROR: Can not found maxp table.\n");
                break;
            case INVALID_PARAMETER:
                printf("ERROR: INVALID TABLE DATA.\n");
                break;
        }
        return -1;
    }
    // get cmap info
    CmapInfo cmapInfo;
    status = getCmapInfo(&info, &cmapInfo);
    if (TTF_ERR(status)) {
        printf("ERROR: Can not found cmap table.\n");
        return -1;
    }
    uint16_t format = getCmapSubTableFormat(&cmapInfo);
    uint16_t glyphIndex;
    if (format == CMAP_FORMAT_4) {
        CmapFormat4Info format4Info;
        cmapReadAsFormat4(&cmapInfo, &format4Info);
        format4SearchGlyphIndex(&format4Info, L'好', &glyphIndex);
        freeCreatedInfo(&format4Info);
    }
    // get loca table
    LocaInfo locaInfo;
    status = getLocaInfo(&info, &locaInfo, headTable.indexToLocFormat);
    if (TTF_ERR(status)) {
        printf("ERROR: Can not found cmap table.\n");
        return -1;
    }
    GlyphLocation glyphLocation;
    getGlyphLocation(&locaInfo, glyphIndex, &glyphLocation);

    freeCreatedInfo(&locaInfo);
    freeCreatedInfo(&cmapInfo);
    freeTTFInfo(&info);
    return 0;
}